// $codepro.audit.disable com.instantiations.assist.eclipse.analysis.audit.rule.effectivejava.alwaysOverridetoString.alwaysOverrideToString, emptyMethod, numericLiterals

//toString - we have no need for a toString method in this class

//empty methods - the mouse inputs are required when even only one is used

// same as others with numeric literals

/**
 * These are the libraries used for this class
 */
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JComboBox;
import javax.swing.JButton;
import javax.swing.DefaultComboBoxModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

/**
 * This class creates the new player frame and controls each action within.
 * 
 * @author Jared Storey
 * @version 1.0
 */
public class SpaceTraderPlayer extends JFrame{
	
	/**
	 * Field textField
	 */
	private final JTextField textField;
	
	/**
	 * Field skillPoints
	 */
	private int skillPoints;
	
	/**
	 * Fields spinners
	 */
	private final JSpinner spinner, spinner_1, spinner_2, spinner_3;
	
	/**
	 * Field btnLaunch
	 */
	private final JButton btnLaunch;
	
	/**
	 * Field label
	 */
	private final JLabel label;
	
	/**
	 * Fields skill ints
	 */
	private int eng, tra, figh, pil;
	
	/**
	 * Field model
	 */
	private final Model model;
	
	/**
	 * Field frame
	 */
	private final JFrame frame;
	
	/**
	 * Field viewer
	 */
	private final View viewer;

	/**
	 * Create the frame including buttons, spinners, and labels.
	 * 
	 * @param model The model used to create the game
	 * @param viewer The viewer for the game
	 */
	public SpaceTraderPlayer(Model model, View viewer) {
		setSize(new Dimension(350, 430));
		setTitle("Player");
		getContentPane().setLayout(null);
		this.model=model;
		frame = this;
		this.viewer=viewer;
		
		spinner = new JSpinner();
		spinner.setModel(new SpinnerNumberModel(1, 1, 10, 1));
		spinner.setBounds(226, 140, 46, 20);
		((JSpinner.DefaultEditor) spinner.getEditor()).getTextField().setEditable(false);
		spinner.addChangeListener(listener);
		getContentPane().add(spinner);
		
		spinner_1 = new JSpinner();
		spinner_1.setModel(new SpinnerNumberModel(1, 1, 10, 1));
		spinner_1.setBounds(226, 171, 46, 20);
		((JSpinner.DefaultEditor) spinner_1.getEditor()).getTextField()
			.setEditable(false);
		spinner_1.addChangeListener(listener);
		getContentPane().add(spinner_1);
		
		spinner_2 = new JSpinner();
		spinner_2.setModel(new SpinnerNumberModel(1, 1, 10, 1));
		spinner_2.setBounds(226, 202, 46, 20);
		((JSpinner.DefaultEditor) spinner_2.getEditor()).getTextField()
			.setEditable(false);
		spinner_2.addChangeListener(listener);
		getContentPane().add(spinner_2);
		
		spinner_3 = new JSpinner();
		spinner_3.setModel(new SpinnerNumberModel(1, 1, 10, 1));
		spinner_3.setBounds(226, 233, 46, 20);
		((JSpinner.DefaultEditor) spinner_3.getEditor()).getTextField()
			.setEditable(false);
		spinner_3.addChangeListener(listener);
		getContentPane().add(spinner_3);
		
		textField = new JTextField();
		textField.setBounds(117, 38, 176, 20);
		getContentPane().add(textField);
		textField.setColumns(10);
		textField.getDocument().addDocumentListener(docListener);
		
		final JLabel lblPlayerName = new JLabel("Player Name");
		lblPlayerName.setBounds(24, 41, 72, 14);
		getContentPane().add(lblPlayerName);
		
		final JComboBox comboBox = new JComboBox();
		comboBox.setModel(new DefaultComboBoxModel(new String[]
				{"Easy", "Medium", "Hard", "Legendary"}));
		comboBox.setMaximumRowCount(4);
		comboBox.setBounds(117, 286, 155, 20);
		getContentPane().add(comboBox);
		
		btnLaunch = new JButton("Launch");
		btnLaunch.setEnabled(false);
		btnLaunch.setBounds(127, 335, 89, 23);
		btnLaunch.addActionListener(actListener);
		getContentPane().add(btnLaunch);
		
		final JLabel lblNewLabel = new JLabel("Engineer");
		lblNewLabel.setBounds(91, 143, 72, 17);
		getContentPane().add(lblNewLabel);
		
		final JLabel lblNewLabel_1 = new JLabel("Trader");
		lblNewLabel_1.setBounds(91, 174, 46, 14);
		getContentPane().add(lblNewLabel_1);
		
		final JLabel lblNewLabel_2 = new JLabel("Fighter");
		lblNewLabel_2.setBounds(91, 205, 46, 17);
		getContentPane().add(lblNewLabel_2);
		
		final JLabel lblNewLabel_3 = new JLabel("Pilot");
		lblNewLabel_3.setBounds(91, 236, 46, 14);
		getContentPane().add(lblNewLabel_3);
		
		final JLabel lblNewLabel_4 = new JLabel("Difficulty");
		lblNewLabel_4.setBounds(24, 289, 72, 14);
		getContentPane().add(lblNewLabel_4);
		
		final JLabel lblNewLabel_5 = new JLabel("Skill Points Remaining:");
		lblNewLabel_5.setHorizontalAlignment(SwingConstants.RIGHT);
		lblNewLabel_5.setBounds(61, 91, 155, 20);
		getContentPane().add(lblNewLabel_5);
		
		label = new JLabel("16");
		label.setHorizontalAlignment(SwingConstants.CENTER);
		label.setBounds(226, 94, 32, 14);
		getContentPane().add(label);
		
	}

	/**
	  * Listener for each spinner. Checks if skill points are 
	  * allocated correctly and updates accordingly. Will set
	  * Launch button to visible if there is also information in the textfield.
	  * 
	  */
	private final ChangeListener listener = new ChangeListener() {
		
		/**
		 * Checks to see if the state has changed
		 * 
		 * @param arg0 The change that is called
		 */
		@Override
		public void stateChanged(ChangeEvent arg0) {
			eng = (Integer) spinner.getValue();
			tra = (Integer) spinner_1.getValue();
			figh = (Integer) spinner_2.getValue();
			pil = (Integer) spinner_3.getValue();
			
			skillPoints = (eng + tra + figh + pil);
			final String x = ("" + (20 - skillPoints));
			label.setText(x);
			if (skillPoints == 20) {
				if(!textField.getText().isEmpty()){
					btnLaunch.setEnabled(true);
				}
				spinner.setModel(new SpinnerNumberModel(skillPoints - tra - figh - pil,
						1, skillPoints - tra - figh - pil, 1));
				((JSpinner.DefaultEditor) spinner.getEditor()).getTextField()
					.setEditable(false);
				spinner_1.setModel(new SpinnerNumberModel(skillPoints - eng - figh - pil,
						1, skillPoints - eng - figh - pil, 1));
				((JSpinner.DefaultEditor) spinner_1.getEditor()).getTextField()
					.setEditable(false);
				spinner_2.setModel(new SpinnerNumberModel(skillPoints - tra - eng - pil,
						1, skillPoints - tra - eng - pil, 1));
				((JSpinner.DefaultEditor) spinner_2.getEditor()).getTextField()
					.setEditable(false);
				spinner_3.setModel(new SpinnerNumberModel(skillPoints - tra - eng - figh,
						1, skillPoints - tra - eng - figh, 1));
				((JSpinner.DefaultEditor) spinner_3.getEditor()).getTextField()
					.setEditable(false);
				
			} else {
				 
				btnLaunch.setEnabled(false);
				spinner.setModel(new SpinnerNumberModel(skillPoints - tra - figh - pil,
						1, 10, 1));
				((JSpinner.DefaultEditor) spinner.getEditor()).getTextField()
					.setEditable(false);
				spinner_1.setModel(new SpinnerNumberModel(skillPoints - eng - figh - pil,
						1, 10, 1));
				((JSpinner.DefaultEditor) spinner_1.getEditor()).getTextField()
					.setEditable(false);
				spinner_2.setModel(new SpinnerNumberModel(skillPoints - tra - eng - pil,
						1, 10, 1));
				((JSpinner.DefaultEditor) spinner_2.getEditor()).getTextField()
					.setEditable(false);
				spinner_3.setModel(new SpinnerNumberModel(skillPoints - tra - eng - figh,
						1, 10, 1));
				((JSpinner.DefaultEditor) spinner_3.getEditor()).getTextField()
					.setEditable(false);
				
			}
		}
		
	};
	
	/**
	 * Listener for the launch button. Sets the skill points
	 * and player name and closes the window. 
	 * Also creates the Universe for the game.
	 * 
	 */
	private final ActionListener actListener = new ActionListener() {
		
		/**
		 * Checks to see if an action has been performed
		 * 
		 * @param arg0 What is called when an action occurs
		 */
		@Override
		public void actionPerformed(ActionEvent arg0) {
			model.getPlayer().setEngSkill(eng);
			model.getPlayer().setTraSkill(tra);
			model.getPlayer().setFighSkill(figh);
			model.getPlayer().setPilSkill(pil);
			model.getPlayer().setName(textField.getText());
			model.setUniverse(new Universe());
			model.setShip(new Ship());
			viewer.setHealth();
			viewer.setFuel();
			viewer.setCurrency();
			viewer.setPlanetName(0);
			viewer.setResource(0);
			viewer.setTechLevel(0);
			viewer.setBay();
			viewer.setMarket(0);
			viewer.resetSell();
			model.getPlayer().setLocation(model.getUniverse().getPlanet(0).getLocation());
			viewer.drawNav();
			for(int i=0; i < viewer.buy.length; i++){
				viewer.buy[i].addMouseListener(new BuyListener1(viewer.buy[i], i, 0));
				viewer.sell[i].addMouseListener(new SellListener1(viewer.buy[i], i, 0));
			}
			viewer.repaint();
			FileWriter file=null;
			try {
				file = new FileWriter("map.txt");
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			finally {
            	try {
					file.close(); // $codepro.audit.disable nullPointerDereference
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
            }
            final PrintWriter writer = new PrintWriter(new BufferedWriter(file));
            for(int i=0; i < model.getUniverse().getPlanetArray().length; i++){
				writer.println(model.getUniverse().getPlanet(i).getLocationString());
			}
			processWindowEvent( new WindowEvent( frame, WindowEvent.WINDOW_CLOSING) );
			writer.close(); // $codepro.audit.disable closeInFinally, closeWhereCreated
		}
	};
	
	/**
	 * Listener for the textfield. Will enable the Launch button
	 * if the skill points are allocated and the textfield 
	 * is not empty, otherwise will disable the button.
	 * 
	 */
	private final DocumentListener docListener = new DocumentListener() {
		
		/**
		 * Another update to check
		 * 
		 * @param e The document that was updated
		 */
		@Override
		public void removeUpdate(DocumentEvent e) {
			update();
		}
		
		/**
		 * Another update to check
		 * 
		 * @param e The document that was updated
		 */
		@Override
		public void insertUpdate(DocumentEvent e) {
			update();
		}
		
		/**
		 * Another update to check
		 * 
		 * @param e The document that was updated
		 */
		@Override
		public void changedUpdate(DocumentEvent e) {
			update();
		}
		
		/**
		 * Checks to see if it appropriate to update the launch button
		 */
		private void update() {
			if (skillPoints >= 20 && !textField.getText().isEmpty()) {
				btnLaunch.setEnabled(true);
			} else {
				btnLaunch.setEnabled(false);
			}
		}
	};
	
	/**
	 * This class handles when items are out of stock
	 * 
	 * @author Jared Storey
	 * @version 1.0
	 */
	public class OutOfStockListener implements MouseListener{
		
		/**
		 * Mouse trigger required for all mouse input
		 * 
		 * @param arg0 The input from the mouse
		 */
		@Override
		public void mouseClicked(MouseEvent arg0) {
		}
		
		/**
		 * Mouse trigger required for all mouse input
		 * 
		 * @param arg0 The input from the mouse
		 */
		@Override
		public void mouseEntered(MouseEvent arg0) {
		}
		
		/**
		 * Mouse trigger required for all mouse input
		 * 
		 * @param arg0 The input from the mouse
		 */
		@Override
		public void mouseExited(MouseEvent arg0) {
		}
		
		/**
		 * Mouse trigger required for all mouse input
		 * 
		 * @param arg0 The input from the mouse
		 */
		@Override
		public void mousePressed(MouseEvent arg0) {
			JOptionPane.showMessageDialog(viewer, "Out Of Stock!.");
		}
		
		/**
		 * Mouse trigger required for all mouse input
		 * 
		 * @param arg0 The input from the mouse
		 */
		@Override
		public void mouseReleased(MouseEvent arg0) {
			// TODO Auto-generated method stub
		}
	}
	
	/**
	 * This class handles when the player buys a good
	 * 
	 * @author Jared Storey
	 * @version 1.0
	 */
	public class BuyListener1 implements MouseListener{
		
		/**
		 * Field i
		 */
		private final int i;
		
		/**
		 * Field x
		 */
		private final int x;
		
		/**
		 * Field jButton
		 */
		private final JButton jButton;

		/**
		 * Determines what happens when an item is clicked for purchase
		 *  
		 * @param jButton The button for the action
		 * @param i The index of the good
		 * @param x the planet index
		 */
		public BuyListener1(JButton jButton, int i, int x) {
			// TODO Auto-generated constructor stub
			this.i=i;
			this.x=x;
			this.jButton=jButton;
		}
		
		/**
		 * Mouse trigger required for all mouse input
		 * 
		 * @param arg0 The input from the mouse
		 */
		@Override
		public void mouseClicked(MouseEvent arg0) {
		}
		
		/**
		 * Mouse trigger required for all mouse input
		 * 
		 * @param arg0 The input from the mouse
		 */
		@Override
		public void mouseEntered(MouseEvent arg0) {
		}
		
		/**
		 * Mouse trigger required for all mouse input
		 * 
		 * @param arg0 The input from the mouse
		 */
		@Override
		public void mouseExited(MouseEvent arg0) {
		}
		
		/**
		 * Mouse trigger required for all mouse input
		 * 
		 * @param arg0 The input from the mouse
		 */
		@Override
		public void mousePressed(MouseEvent arg0) {
			final Planet planet = model.getUniverse().getPlanet(0);
			if(planet.getMarket().getGoodsArray()[i].getCount()
					== 0){
				JOptionPane.showMessageDialog(viewer, "Out Of Stock!.");
			}
			else {
				final SpaceTraderBuy frame = new SpaceTraderBuy(model, 
						jButton, viewer, i, x);
				frame.setVisible(true);
				viewer.repaint();
			}
		}
		
		/**
		 * Mouse trigger required for all mouse input
		 * 
		 * @param arg0 The input from the mouse
		 */
		@Override
		public void mouseReleased(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}
	}
	
	/**
	 * This class handles when the player tries to sell a good.
	 * 
	 * @author Jared Storey
	 * @version 1.0
	 */
	public class SellListener1 implements MouseListener{
		
		/**
		 * Field i
		 */
		private final int i;
		
		/**
		 * Field x
		 */
		private final int x;
		
		/**
		 * Field jButton
		 */
		private final JButton jButton;
		
		/**
		 * Determines what happens when an item is clicked for selling
		 *  
		 * @param jButton The button for the action
		 * @param i The index of the good
		 * @param x the planet index
		 */
		public SellListener1(JButton jButton, int i, int x) {
			// TODO Auto-generated constructor stub
			this.i=i;
			this.x=x;
			this.jButton=jButton;
		}
		
		/**
		 * Mouse trigger required for all mouse input
		 * 
		 * @param arg0 The input from the mouse
		 */
		@Override
		public void mouseClicked(MouseEvent arg0) {
		}
		
		/**
		 * Mouse trigger required for all mouse input
		 * 
		 * @param arg0 The input from the mouse
		 */
		@Override
		public void mouseEntered(MouseEvent arg0) {
		}
		
		/**
		 * Mouse trigger required for all mouse input
		 * 
		 * @param arg0 The input from the mouse
		 */
		@Override
		public void mouseExited(MouseEvent arg0) {
			}
		
		/**
		 * Checks to see what the appropriate response is when the mouse is clicked
		 * 
		 * @param arg0 The input from the mouse
		 */
		@Override
		public void mousePressed(MouseEvent arg0) {
			final Planet planet = model.getUniverse().getPlanet(0);
			if(planet.getMarket().getGood()[i].mtlu >
				planet.getTech()){
				JOptionPane.showMessageDialog(viewer, "Not Allow to Sell!.");
			}
			else if(model.getShip().getGoodsArray()[i].getSold() == 0){
				JOptionPane.showMessageDialog(viewer, "Out Of Stock!.");
			}
			else{
				final SpaceTraderSell frame = new SpaceTraderSell(model, 
						jButton, viewer, i, x);
				frame.setVisible(true);
				viewer.repaint();
			}
		}
		
		/**
		 * Mouse trigger required for all mouse input
		 * 
		 * @param arg0 The input from the mouse
		 */
		@Override
		public void mouseReleased(MouseEvent arg0) {
			// TODO Auto-generated method stub
		}
	}
	
}
